package com.eian.boot.module.system.role.service;

import com.eian.boot.common.enums.DataScopeEnum;
import com.eian.boot.module.system.associations.role.dept.service.RoleDeptRelationService;
import com.eian.boot.module.system.associations.user.dept.service.UserDeptRelationService;
import com.eian.boot.module.system.dept.service.SysDeptService;
import com.eian.boot.module.system.role.model.entity.SysRoleEntity;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 数据权限服务
 *
 * @author alex.meng
 */
@Service
@AllArgsConstructor
public class DataScopeService {

    private final SysRoleService roleService;
    private final UserDeptRelationService userDeptRelationService;
    private final SysDeptService deptService;
    private final RoleDeptRelationService roleDeptRelationService;

    /**
     * 构建数据权限SQL条件
     */
    public String buildDataScopeSQL(Long userId, String deptAlias, String userAlias) {
        // 获取用户所有角色
        List<SysRoleEntity> roles = roleService.getUserRoles(userId);
        if (roles == null || roles.isEmpty()) {
            return StringUtils.isNotBlank(userAlias) ? userAlias + ".id = " + userId : "1=0";
        }

        // 找出最大权限范围
        DataScopeEnum maxScope = findMaxDataScope(roles);

        // 根据权限范围构建SQL
        switch (maxScope) {
            case ALL:
                return "1=1";

            case CUSTOM:
                return buildCustomDataScopeSQL(roles, deptAlias);

            case DEPT:
                return buildDeptDataScopeSQL(userId, deptAlias);

            case DEPT_AND_CHILD:
                return buildDeptAndChildDataScopeSQL(userId, deptAlias);

            case SELF:
                return buildSelfDataScopeSQL(userId, userAlias);

            default:
                return "1=0";
        }
    }

    /**
     * 找出最大权限范围
     */
    private DataScopeEnum findMaxDataScope(List<SysRoleEntity> roles) {
        return roles.stream()
                .map(role -> DataScopeEnum.getByValue(role.getDataScope()))
                .min((a, b) -> Integer.compare(a.getValue(), b.getValue()))
                .orElse(DataScopeEnum.SELF);
    }

    /**
     * 自定义数据权限SQL
     */
    private String buildCustomDataScopeSQL(List<SysRoleEntity> roles, String deptAlias) {
        Set<Long> deptIds = new HashSet<>();

        for (SysRoleEntity role : roles) {
            if (DataScopeEnum.CUSTOM.getValue().equals(role.getDataScope())) {
                List<Long> roleDeptIds = roleDeptRelationService.getDeptIdsByRoleId(role.getId());
                deptIds.addAll(roleDeptIds);
            }
        }

        if (deptIds.isEmpty()) {
            return "1=0";
        }

        String deptIdsStr = deptIds.stream()
                .map(String::valueOf)
                .collect(Collectors.joining(","));

        return (StringUtils.isNotBlank(deptAlias) ? deptAlias + "." : "") + "dept_id IN (" + deptIdsStr + ")";
    }

    /**
     * 本部门数据权限SQL
     */
    private String buildDeptDataScopeSQL(Long userId, String deptAlias) {
        Long deptId = userDeptRelationService.getMainDeptIdByUserId(userId);
        if (deptId == null) {
            return "1=0";
        }
        return (StringUtils.isNotBlank(deptAlias) ? deptAlias + "." : "") + "dept_id = " + deptId;
    }

    /**
     * 本部门及以下数据权限SQL
     */
    private String buildDeptAndChildDataScopeSQL(Long userId, String deptAlias) {
        Long deptId = userDeptRelationService.getMainDeptIdByUserId(userId);
        if (deptId == null) {
            return "1=0";
        }

        List<Long> deptIds = deptService.getDeptAndChildrenIds(deptId);
        if (deptIds.isEmpty()) {
            return "1=0";
        }

        String deptIdsStr = deptIds.stream()
                .map(String::valueOf)
                .collect(Collectors.joining(","));

        return (StringUtils.isNotBlank(deptAlias) ? deptAlias + "." : "") + "dept_id IN (" + deptIdsStr + ")";
    }

    /**
     * 仅本人数据权限SQL
     */
    private String buildSelfDataScopeSQL(Long userId, String userAlias) {
        if (StringUtils.isBlank(userAlias)) {
            return "1=0";
        }
        return userAlias + ".id = " + userId;
    }
}

